package gdt.entity;

import gdt.entity.AbstractSecureEntity;
import gdt.entity.embeddable.Address;
import gdt.entity.enumeration.WeekDay;

import java.io.Serializable;
import java.lang.String;
import java.util.LinkedList;
import java.util.List;
import java.util.TimeZone;
import javax.persistence.*;

import org.hibernate.validator.Email;
import org.hibernate.validator.NotEmpty;
import org.hibernate.validator.NotNull;
import org.hibernate.validator.Pattern;
import org.hibernate.validator.Valid;

import static javax.persistence.FetchType.LAZY;
import static javax.persistence.CascadeType.ALL;

/**
 * Entity that represents a group that uses the system. It is compound of
 * members and projects. It has a list of clients and can be associated with
 * holidays and announcements.
 */

@NamedQuery(name="findGroupByName",query="select g from Group_ g where g.name like :name")
@Entity(name = "Group_")
public class Group extends AbstractSecureEntity implements Serializable {

	private static final long serialVersionUID = 1L;

	@NotNull
	@NotEmpty
	private String name;

	@Valid
	@Embedded
	private Address address = new Address();

	@Email
	private String email;

	@Pattern(regex="[0-9]{0,50}")
	private String phone;

	@Pattern(regex="[0-9]{0,50}")
	private String fax;

	private String url;

	private String logo = "default.jpg";

	private TimeZone timezone;

	private int workDayLength = 8;

	private WeekDay weekStartDay = WeekDay.MONDAY;

	private boolean isWorkingMonday = true;

	private boolean isWorkingTuesday = true;

	private boolean isWorkingWednesday = true;

	private boolean isWorkingThursday = true;

	private boolean isWorkingFriday = true;

	private boolean isWorkingSaturday = true;

	private boolean isWorkingSunday = true;

	@OneToMany(fetch = LAZY, mappedBy = "group", cascade = ALL)
	private List<Project> projects = new LinkedList<Project>();

	@OneToMany(fetch = LAZY, mappedBy = "group", cascade = ALL)
	private List<Client> clients = new LinkedList<Client>();

	@OneToMany(fetch = LAZY, mappedBy = "group", cascade = ALL)
	private List<Member> members = new LinkedList<Member>();

	@OneToMany(fetch = LAZY, mappedBy = "assignedGroup", cascade = ALL)
	private List<GroupHoliday> holidays = new LinkedList<GroupHoliday>();

	@OneToMany(fetch = LAZY, mappedBy = "group", cascade = ALL)
	private List<GroupAnnouncement> announcements = new LinkedList<GroupAnnouncement>();

	public Group() {
		super();
	}

	// ********************** Accessor Methods ********************** //

	public String getName() {
		return this.name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Address getAddress() {
		return this.address;
	}

	public void setAddress(Address address) {
		this.address = address;
	}

	public String getEmail() {
		return this.email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getPhone() {
		return this.phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	public String getFax() {
		return fax;
	}

	public void setFax(String fax) {
		this.fax = fax;
	}

	public String getUrl() {
		return this.url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public String getLogo() {
		return this.logo;
	}

	public void setLogo(String logo) {
		this.logo = logo;
	}

	public TimeZone getTimezone() {
		return this.timezone;
	}

	public void setTimezone(TimeZone timezone) {
		this.timezone = timezone;
	}

	public int getWorkDayLength() {
		return this.workDayLength;
	}

	public void setWorkDayLength(int workDayLength) {
		this.workDayLength = workDayLength;
	}

	public WeekDay getWeekStartDay() {
		return this.weekStartDay;
	}

	public void setWeekStartDay(WeekDay weekStartDay) {
		this.weekStartDay = weekStartDay;
	}

	public boolean getIsWorkingMonday() {
		return this.isWorkingMonday;
	}

	public void setIsWorkingMonday(boolean isWorkingMonday) {
		this.isWorkingMonday = isWorkingMonday;
	}

	public boolean getIsWorkingTuesday() {
		return this.isWorkingTuesday;
	}

	public void setIsWorkingTuesday(boolean isWorkingTuesday) {
		this.isWorkingTuesday = isWorkingTuesday;
	}

	public boolean getIsWorkingWednesday() {
		return this.isWorkingWednesday;
	}

	public void setIsWorkingWednesday(boolean isWorkingWednesday) {
		this.isWorkingWednesday = isWorkingWednesday;
	}

	public boolean getIsWorkingThursday() {
		return this.isWorkingThursday;
	}

	public void setIsWorkingThursday(boolean isWorkingThursdayday) {
		this.isWorkingThursday = isWorkingThursdayday;
	}

	public boolean getIsWorkingFriday() {
		return this.isWorkingFriday;
	}

	public void setIsWorkingFriday(boolean isWorkingFriday) {
		this.isWorkingFriday = isWorkingFriday;
	}

	public boolean getIsWorkingSaturday() {
		return this.isWorkingSaturday;
	}

	public void setIsWorkingSaturday(boolean isWorkingSaturday) {
		this.isWorkingSaturday = isWorkingSaturday;
	}

	public boolean getIsWorkingSunday() {
		return this.isWorkingSunday;
	}

	public void setIsWorkingSunday(boolean isWorkingSunday) {
		this.isWorkingSunday = isWorkingSunday;
	}

	public void setProjects(List<Project> projects) {
		this.projects = projects;
	}

	public List<Project> getProjects() {
		return projects;
	}

	public void setClients(List<Client> clients) {
		this.clients = clients;
	}

	public List<Client> getClients() {
		return clients;
	}

	public void setMembers(List<Member> members) {
		this.members = members;
	}

	public List<Member> getMembers() {
		return members;
	}

	public void setHolidays(List<GroupHoliday> holidays) {
		this.holidays = holidays;
	}

	public List<GroupHoliday> getHolidays() {
		return holidays;
	}

	public void setAnnouncements(List<GroupAnnouncement> announcements) {
		this.announcements = announcements;
	}

	public List<GroupAnnouncement> getAnnouncements() {
		return announcements;
	}

	// *********************** Adder Methods *********************** //

	public void addMember(Member member) {
		getMembers().add(member);
		member.setGroup(this);
	}

	public void addProject(Project project) {
		getProjects().add(project);
		project.setGroup(this);
	}

	public void addClient(Client client) {
		getClients().add(client);
		client.setGroup(this);
	}

	public void addAnnouncement(GroupAnnouncement announcement) {
		getAnnouncements().add(announcement);
		announcement.setGroup(this);
	}

	public void addHoliday(GroupHoliday holiday) {
		getHolidays().add(holiday);
		holiday.setAssignedGroup(this);
	}

	// *********************** Remover Methods *********************** //

	public void removeMember(Member member) {
		getMembers().remove(member);
	}

	public void removeProject(Project project) {
		getProjects().remove(project);
	}

	public void removeClient(Client client) {
		getClients().remove(client);
	}

	public void removeAnnouncement(GroupAnnouncement announcement) {
		getAnnouncements().remove(announcement);
	}

	public void removeHoliday(GroupHoliday holiday) {
		getHolidays().remove(holiday);
	}

}
